package com.bowen.demo.demo009;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <h3>java-study</h3>
 * <p>Java流应用</p>
 * @author : zhang.bw
 * @date : 2021-05-30 22:42
 **/
public class JavaStreamDemo {
	public static void main(String[] args) {

		/**
		 * 过滤
		 */
		List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
		List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
		System.out.println(filtered);

		/**
		 * 获取空字符串的数量
		 */
		long count = strings.stream().filter(string -> string.isEmpty()).count();
		System.out.println(count);

		/**
		 * 将一个List中元素的某一属性取出来作为一个list，并做过滤
		 */
		List<User> users = new ArrayList<>();
		User u1 = new User(1L,"zhangsan","男","123456");
		User u2 = new User(2L,"LISI","男","123456");
		User u3 = new User(3L,"XIAOHUA","女","123456");
		users.add(u1);
		users.add(u2);
		users.add(u3);
		List<Long> names=  users.stream().filter(Objects::nonNull).map(User::getId).collect(Collectors.toList());
		//或者
		List<Long> names1= users.stream().filter(Objects::nonNull).map(u->u.getId()).collect(Collectors.toList());

		/**
		 * 将List转换成Map
		 */
		//key:id value:name
		Map<Long, String> map = users.stream().collect(Collectors.toMap(p -> p.getId(), p -> p.getName()));
		//或者,第三个参数表示如果key重复保留k1,舍弃k2。
		Map<Long, String> map2 = users.stream().collect(Collectors.toMap(User::getId,User::getName,(k1,k2)->k1));
		//key:id value:user
		Map<Long, User> map3 = users.stream().collect(Collectors.toMap(p -> p.getId(), p->p));
		//遍历map，包括k,v。map.values.forEach()不能遍历Key
		map3.forEach((k,v)-> System.out.println("k:v="+k+":"+v));

		/**
		 * 使用sorted对List排序
		 * Comparator.comparing(User::getId)表示以id作为排序的数据。
		 */
		//降序，默认是升序
		List<User> list= users.stream().sorted(Comparator.comparing(User::getId).reversed()).collect(Collectors.toList());
		List<User> list2= users.stream().sorted(Comparator.comparing(User::getId)).collect(Collectors.toList());
		//遍历list
		list.forEach(System.out::println);
		list2.forEach(System.out::println);

		/**
		 * 对List分组存入一个Map
		 */
		//按照性别分组
		Map<String,List<User>> map4=users.stream().collect(Collectors.groupingBy(User::getSex));
		map4.forEach((k,v)-> System.out.println("k:v="+k+":"+v));

		/**
		 *  使用map转换大写
		 */
		List<String> list1 = new ArrayList<>();
		list1.add("a");
		list1.add("b");
		list1.add("c");
		List<String> list8 = list1.stream().map(String::toUpperCase).collect(Collectors.toList());
		System.out.println(list8);

		/**
		 * flatMap和map
		 * latMap与map的区别在于 flatMap是将一个流中的每个元素都转成一个个流，flatMap之后得到的是每个流中元素的总的集合，即对每个流进行了二次遍历取出其中的元素，融合到总的集合中。
		 */
		//map
		List<String> str = Arrays.asList("a,b,c", "d,e", "f");
		List<String[]> list10 = str.stream().map(s -> s.split(",")).collect(Collectors.toList());
		list10.forEach(p-> System.out.print(Arrays.toString(p)+","));//[a, b, c],[d, e],[f]

		//flatMap
		List<String> list11 = str.stream().map(s -> s.split(",")).flatMap(Arrays::stream).sorted(Comparator.comparing(p->p.toString()).reversed()).collect(Collectors.toList());
		System.out.println(list11);//[f, e, d, c, b, a]

		/**
		 * limit和skip
		 *limit(5)限制只要前五条，skip(2)跳过前两条。特别注意如果limit和skip配合sorted使用，需先进行limit和skip。
		 */
		List<Long> ids=users.stream().map(User::getId).limit(5).skip(2).collect(Collectors.toList());
		ids.forEach(System.out::println);//0-9 输出了 2 3 4

		/**
		 * anyMatch
		 */
		Map<Long, String> map10 = new HashMap<>();
		map10.put(1L, "1号");
		map10.put(2L, "2号");
		map10.put(3L, "3号");
		List<User> list12 = new ArrayList<>();
		list12.add(new User(1L,"XIAOHUA1","女","123456"));
		list12.add(new User(2L,"XIAOHUA2","女","123456"));
		list12.add(new User(3L,"XIAOHUA3","女","123456"));
		boolean f = false;
		//所有都匹配的时候才会返回true
		for(Map.Entry<Long,String> entry:map10.entrySet()){
			f = list12.stream().anyMatch(p ->
					Objects.equals(entry.getKey(), p.getId())
			);
		}


		/**
		 * list交集和并集
		 */
		List<String> list13 = new ArrayList<>();
		list13.add("1");
		list13.add("2");
		list13.add("3");
		list13.add("4");
		List<String> list14 = new ArrayList<>();
		list14.add("3");
		list14.add("4");
		list14.add("5");
		list14.add("6");

		//交集,或使用list13.retainAll(list14);
		List<String> intersection=list13.stream().filter(i->list14.contains(i)).collect(Collectors.toList());
		System.out.println("交集：");
		intersection.forEach(System.out::println);
		//差集，或使用list13.removeAll(list14);
		List<String> reduce=list13.stream().filter(i->!list14.contains(i)).collect(Collectors.toList());
		System.out.println("差集：");
		reduce.forEach(System.out::println);
		//并集
		List<String> listAll = list13;
		listAll.addAll(list14);
		System.out.println("并集：");
		listAll.forEach(System.out::println);
		//去重并集，或使用list13.removeAll(list14);list13.addAll(list14);
		List<String> listAllDistinct = listAll.stream().distinct().collect(Collectors.toList());
		System.out.println("去重并集：");
		listAllDistinct.forEach(System.out::println);
	}
}
